package s.f.contribuyentes;

import s.f.lang.Cadena;
import s.f.util.Validacion;
import java.rmi.RemoteException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import javax.ejb.CreateException;
import javax.ejb.EJBException;
import javax.ejb.SessionBean;
import javax.ejb.SessionContext;

/**
 * EJB de session sin estado Genera documentación para una persona fisica.
 *
 * @author Froy
 */
public class EmpleadosContribuyentesController implements SessionBean {

    //Este método corresponde al método de la creación de beans de la interfaz EJBHome
    public void ejbCreate() throws CreateException, RemoteException {
    }

    @Override
    public void setSessionContext(SessionContext ctx) throws EJBException, RemoteException {
    }

    @Override
    public void ejbRemove() throws EJBException, RemoteException {
    }

    @Override
    public void ejbActivate() throws EJBException, RemoteException {
    }

    @Override
    public void ejbPassivate() throws EJBException, RemoteException {
    }
    
    /**
     * 
     * @param fnacimeinto
     * @param nombre
     * @param appaterno
     * @param apmaterno
     * @param sexo
     * @param estado
     * @return 
     */
    public String getCURP(String fnacimeinto,
            String nombre, String appaterno, String apmaterno,
            String sexo, int estado) {

        String resultado;
        /*
         * 1)------- Limpiar palabras de letras acentuadas, preposiciones,
         * artículos ,conjunciones, caracteres especiales y cambiando a
         * mayúsculas.
         */
        nombre = Formato.PalabraCURP(nombre);
        appaterno = Formato.PalabraCURP(appaterno);
        apmaterno = Formato.PalabraCURP(apmaterno);
        sexo = sexo.toUpperCase();

        /*
         * 2)------- Verficar en nombres compuestos los nombres JOSÉ y MARÍA. J,
         * J., Ma, Ma., ...
         */
        if (Validaciones.isNombreCompuesto(nombre)) {
            nombre = Validaciones.getNameDiffJMsiContiene(nombre);
        }

        /*
         * 3)-------
         */
        resultado = Validaciones.filtroCURP(fnacimeinto, nombre, appaterno, apmaterno, sexo, estado);


        //[F, E, T, O, -, 85, 07, 11] limpiando... 
        resultado = Cadena.cleanList(resultado);

        //FETO - FETX
        if (resultado.length() >= 4) {
            resultado = resultado.replace(resultado.substring(0, 4), Formato.palabrasInconvenientesCURP(resultado.substring(0, 4)));
        }

        return resultado;
    }
    
    /**
     * Cálculo del RFC para <strong>Persona Moral.</strong> <p>Regla 1: 1ra
     * Forma</p> <ul> <li>La primera letra del apellido paterno y la siguiente
     * vocal del mismo.</li> <li>La primera letra del apellido materno.</li>
     * <li>La primera letra del nombre.</li> </ul> <p>Regla 2: Formato de la
     * fecha de nacimiento, estos serán en números arábigos.</p> <ul> <li>Año:
     * Se tomará encuenta las dos últimas cifras del año.</li> <li>Mes: Se
     * tomará el número del mes 07=Julio.</li> <li>Día: Se tomará el día de
     * nacimiento 02.</li> </ul> <p>Regla 3: Letras compuestas en
     * nombre,apellido paterno o materno.</p> <ul> <li>En letras compuestas como
     * Ll o Ch sólo se tomará en cuenta L o C.</li> </ul> <p>Regla 4: 2da Forma
     * Apellido paterno con una o dos letras.</p> <ul> <li>La primera letra del
     * apellido paterno.</li> <li>La primera letra del apellido materno.</li>
     * <li>La primera y segunda letra del nombre.</li> </ul> <p>Regla 5:
     * Apellido paterno o materno compuestos.</p> <ul> <li>Se tomará la primera
     * palabra que correspoda: [San] Martín.</li> </ul> <p>Regla 6: Eliminar en
     * nombres compuestos JOSÉ y MARÍA.</p> <p>Regla 7: 3ra Forma Un sólo
     * apellido paterno o materno.</p> <ul> <li>La primera y segunda letra del
     * apellido paterno o materno.</li> <li>La primera y segunda letra del
     * nombre.</li> </ul> <p>Regla 8: No se tomarán como elementos clave
     * artículos,preposiciones,conjunciones o cotracciones.</p> <p>Regla 9:
     * Remplazar conjunto de letras inconvenientes.</p>
     *
     * @param fnacimeinto
     * @param nombre
     * @param appaterno
     * @param apmaterno
     * @return RFC
     */
    public String getRFCPersonaFisica(String fnacimeinto,
            String nombre, String appaterno, String apmaterno) {

        String res;
        String homonima1 = "";

        /*
         * 1)------- Limpiar palabras de letras acentuadas, preposiciones,
         * artículos ,conjunciones, caracteres especiales y cambiando a
         * mayúsculas.
         */
        nombre = Formato.PalabraRFCFisica(nombre);
        appaterno = Formato.PalabraRFCFisica(appaterno);
        apmaterno = Formato.PalabraRFCFisica(apmaterno);

        /*
         * 1.1) Antes de eliminar JOSE y MARIA obetenr la homonima. Para obtener
         * la homonima sólo es necesario el NOMBRE COMPLETO.
         */
        String nombreCompleto = Validacion.unirNombre(nombre, appaterno, apmaterno);

        if (!fnacimeinto.isEmpty()) {
            homonima1 = Cadena.cleanList(Validaciones.getHomonimiaRFC(nombreCompleto, Integer.parseInt(fnacimeinto.substring(6, 10))));
        }

        /*
         * 2)------- Verficar en nombres compuestos los nombres JOSÉ y MARÍA.
         * (Ma.) sería diferente de María.
         */
        if (Validaciones.isNombreCompuesto(nombre)) {
            nombre = Validaciones.getNameDiffJMsiContiene(nombre);
        }

        /*
         * 3)-------
         */
        //Si apellido patenro consta de una o dos letras.
        if (appaterno.length() <= 2 && !appaterno.isEmpty()) {
            res = Validaciones.forma2SiApellidoPaternoMenor2LetrasRFCPFisica(fnacimeinto, nombre, appaterno, apmaterno);
        } //Si uno de los apellidos esta vacio.
        else if (appaterno.isEmpty() || apmaterno.isEmpty()) {
            res = Validaciones.forma3SiApellidosVaciosRFCPFisica(fnacimeinto, nombre, appaterno, apmaterno);
        } //Si se cuenta con todos los campos.
        else {
            res = Validaciones.forma1TodoslosCamposRFCPFisica(fnacimeinto, nombre, appaterno, apmaterno);
        }

        //[F, E, T, O, -, 85, 07, 11] limpiando... 
        //De acuerdo a: http://www.diputados.gob.mx/LeyesBiblio/abro/lia/LIA_cant01_29mar96.pdf
        //Toda Ñ que se presente en el rfc será cambiada a &. pag.32

        res = Cadena.cleanList(res).replace('Ñ', '&');

        //FETO - FETX
        if (res.length() >= 4) {
            res = res.replace(res.substring(0, 4), Formato.palabrasInconvenientesRFC(res.substring(0, 4)));
        }

        if (!homonima1.isEmpty()) {
            //Obteniendo dígito verificador
            String dv = Validaciones.getDigitoVerificadorRFC(res.concat(homonima1));
            res = res.concat(homonima1).concat(dv);
        }

        return res;
    }
    
    /**
     * Calcular el RFC de una Persona Moral.
     *
     * @param razonSocial
     * @param fecha
     * @return
     */
    public String getRFCPersonaMoral(String razonSocial, String fecha) {
        String anio = fecha.substring(8, 10);
        String anioHomoclave = fecha.substring(6, 10);
        String mes = fecha.substring(3, 5);
        String dia = fecha.substring(0, 2);

        String grazonSocial = razonSocial.replace(".", "").replace(",", "").trim();
        String h = Validaciones.getHomoclaveMoral(grazonSocial, Integer.parseInt(anioHomoclave));

        Map mapCaracteresEspeciales = new HashMap();
        mapCaracteresEspeciales.put("@", "ARROBA");
        mapCaracteresEspeciales.put("'", "APOSTROFE");
        mapCaracteresEspeciales.put("%", "PORCINETO");
        mapCaracteresEspeciales.put("#", "NUMERO");
        mapCaracteresEspeciales.put("!", "ADMIRACION");
        mapCaracteresEspeciales.put(".", "PUNTO");
        mapCaracteresEspeciales.put("$", "PESOS");
        mapCaracteresEspeciales.put("\"", "COMIMLLAS");
        mapCaracteresEspeciales.put("-", "GUION");
        mapCaracteresEspeciales.put("/", "DIAGONAL");
        mapCaracteresEspeciales.put("+", "SUMA");
        mapCaracteresEspeciales.put("(", "ABRE PARENTESIS");
        mapCaracteresEspeciales.put(")", "CIERRA PRENTESIS");

        ArrayList lista = new ArrayList();

        //1) limpiar Razón Social
        razonSocial = Formato.PalabraRFCMoral(razonSocial);

        /*
         * 2) Eliminar el tipo de Razón Social Cuando se valide la razón social,
         * se tome en cuenta todos los tipos de razón social.
         *
         */
        //int lastindexComa = razonSocial.lastIndexOf(",");
        //razonSocial = razonSocial.substring(0, lastindexComa);


        if (Validaciones.hasIniciales(razonSocial)) {
            razonSocial = razonSocial.replace(".", " ");
        }

        String[] palabra = razonSocial.split(" ");
        int totalPalabras = palabra.length;

        if (totalPalabras >= 3) {
            for (int i = 0; lista.size() < 3; i++) {
                if (palabra[i].isEmpty()) {
                    i++;
                }
                lista.add(palabra[i].charAt(0));
            }
        } else if (totalPalabras == 2) {
            lista.add(palabra[0].charAt(0));
            lista.add(palabra[1].charAt(0));
            lista.add(palabra[1].charAt(1));
        } else if (totalPalabras == 1 && palabra[0].length() >= 3) {
            lista.add(palabra[0].charAt(0));
            lista.add(palabra[0].charAt(1));
            lista.add(palabra[0].charAt(2));
        } else if (totalPalabras == 1 && palabra[0].length() == 2) {
            lista.add(palabra[0].charAt(0));
            lista.add(palabra[0].charAt(1));
            lista.add("X");
        } else if (totalPalabras == 1 && palabra[0].length() == 1) {
            lista.add(palabra[0].charAt(0));
            lista.add("X");
            lista.add("X");
        }

        lista.add(anio);
        lista.add(mes);
        lista.add(dia);
        lista.add(h);

        //http://www.fiscalia.com/modules.php?name=Foros&sop=verTopico&idTema=27635&idCat=13&p=1#153876
        lista.add(Validaciones.getDigitoVerificadorMoral("*" + Cadena.cleanList(lista.toString())));

        return Cadena.cleanList(lista.toString());
    }
    
}
